package utils

import (
	"fmt"
	"time"

	"golang.org/x/crypto/ssh"
)

type SshClient struct {
	Host       string      // ip
	Port       int64       // 端口
	Username   string      // 用户名
	Password   string      // 密码
	Client     *ssh.Client // ssh client
	LastResult string      // 最近一次运行的结果
	Error      error       // 错误信息
}

func (m *SshClient) SshCreate(host string, port int64, username, password string) {
	m.Host = host
	m.Port = port
	m.Username = username
	m.Password = password

	config := &ssh.ClientConfig{
		User:            m.Username,
		Auth:            []ssh.AuthMethod{ssh.Password(m.Password)},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         1 * time.Second, // ssh验证错误时将在一秒内返回
	}
	// IP:PORT
	addr := fmt.Sprintf("%s:%d", m.Host, m.Port)
	// 创建客户端
	client, err := ssh.Dial("tcp", addr, config)
	if err != nil {
		fmt.Printf("[SSH] 创建ssh-client失败 [err=%s]\n", err.Error())
		m.Error = err
		return
	}
	m.Client = client
}

// SshClose 关闭ssh-client
func (m *SshClient) SshClose() {
	m.Client.Close()
}

// SshRun 执行shell
func (m *SshClient) SshRun(shell string) string {
	session, err := m.Client.NewSession()
	if err != nil {
		fmt.Printf("[SSH] 创建ssh-client-session失败 [err=%s]\n", err.Error())
		return err.Error()
	}
	defer session.Close()

	// 执行shell并获取输出
	output, err := session.CombinedOutput(shell)
	if err != nil {
		fmt.Printf("[SSH] 执行ssh-client-session-shell失败 [err=%s]\n", err.Error())
		m.Error = err
	} else {
		m.LastResult = string(output)
		fmt.Printf("[SSH] 执行ssh-client-session-shell成功 [shell=%s]\n%s", shell, m.LastResult)
	}
	return m.LastResult
}
